package com.robusta.spreadsheet.model.impl;

import com.robusta.spreadsheet.model.*;
import com.robusta.spreadsheet.model.exception.WorkbookException;

import java.util.Iterator;
import java.util.List;

import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.collect.Lists.newArrayList;
import static com.robusta.spreadsheet.model.impl.RobustaWorkbookFactory.newCell;

/**
 */
public class RobustaRow implements Row {
    private org.apache.poi.ss.usermodel.Row row;
    private SheetHeaders sheetHeaders;
    private WorksheetTemplate worksheetTemplate;
    private List<Cell> cells = newArrayList();
    private Worksheet parent;

    protected RobustaRow(Worksheet parent, org.apache.poi.ss.usermodel.Row row, SheetHeaders sheetHeaders, WorksheetTemplate worksheetTemplate) throws WorkbookException {
        this.parent = parent;
        this.row = row;
        this.sheetHeaders = sheetHeaders;
        this.worksheetTemplate = worksheetTemplate;
        initializeCells();
    }

    private void initializeCells() throws WorkbookException {
        for(int position = worksheetTemplate.getStartColumnIndex(); position < row.getLastCellNum(); position++) {
            cells.add(newCell(this, row.getCell(position), sheetHeaders.getHeaderAt(position)));
        }
    }

    @Override
    public Cell getCellAt(int position) throws WorkbookException {
        checkArgument(position >= worksheetTemplate.getStartColumnIndex() && position < row.getLastCellNum(), String.format("This row does not have a cell defined at position: %s", position));
        return computeRelativeIndexAndGetCellFromList(position);
    }

    private Cell computeRelativeIndexAndGetCellFromList(int position) {
        return cells.get(position - worksheetTemplate.getStartColumnIndex());
    }

    @Override
    public Cell getCellFor(HeaderCell headerCell) throws WorkbookException {
        return getCellByHeaderText(headerCell.getText());
    }

    @Override
    public Cell getCellByHeaderText(String headerText) throws WorkbookException {
        return getCellAt(sheetHeaders.getHeaderByText(headerText).getPosition());
    }

    @Override
    public int rowIndex() {
        return row.getRowNum();
    }

    @Override
    public Iterator<Cell> iterator() {
        return cells.iterator();
    }

    @Override
    public Worksheet owner() {
        return parent;
    }

    @Override
    public String toString() {
        final StringBuilder sb = new StringBuilder();
        sb.append("RobustaRow");
        sb.append("{rowIndex=").append(row.getRowNum());
        sb.append(", cells=").append(cells);
        sb.append('}');
        return sb.toString();
    }
}
